﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Bioinformatics.Types;

namespace Bioinformatics.Utilities
{
    public class PsomlBenchmarkManager
    {
        public PsomlBenchmarkManager(IBenchmarkable[] benchmarkableAlgorithms)
        {
            CurrentBenchmarkLog = new Dictionary<string, BenchmarkLog>();

            //create benchmark hooks into all passed algorithms
            CurrentBenchmarks = new Dictionary<string, Benchmarker>();
            for (int i = 0; i < benchmarkableAlgorithms.Length; i++)
            {
                //create benchmarker for algorithm
                Benchmarker benchmarker = benchmarkableAlgorithms[i].GetBenchmarker();
                //subscribe to benchmark complete event so performance data can be added to log
                benchmarker.BenchmarkComplete += compilePerformanceResults;
                //add to dictionary
                CurrentBenchmarks.Add(benchmarker.ToString(), benchmarker);
            }
        }

        public PsomlConfiguration CurrentConfiguration { get; set; }
        public Dictionary<string, BenchmarkLog> CurrentBenchmarkLog { get; set; }
        public Dictionary<string, Benchmarker> CurrentBenchmarks { get; private set; }

        public void BeginBenchmark(string algorithmName)
        {
            CurrentBenchmarks[algorithmName].Start();
        }

        public void ExportBenchmarkLog(string path)
        {
            var fstream = File.OpenWrite(path);
            var binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(fstream, CurrentBenchmarkLog);
            fstream.Close();
        }

        public void ImportBenchmarkLog(string path)
        {
            var fstream = File.OpenRead(path);
            var binaryFormatter = new BinaryFormatter();
            CurrentBenchmarkLog = (Dictionary<string, BenchmarkLog>) binaryFormatter.Deserialize(fstream);
            fstream.Close();
        }

        private void compilePerformanceResults(Benchmarker sender, BenchmarkLog performanceResults)
        {
            CurrentBenchmarkLog[sender.ToString()] = performanceResults;
            BenchmarkComplete(this, EventArgs.Empty);
        }

        public event EventHandler BenchmarkComplete;
    }
}